<?php

namespace common\behavior\CommonMessagePushing;

use common\model\ProjectMemberModel;
use common\model\ProjectModel;
use common\model\TaskModel;
use common\model\UserModel;
use common\service\BehaviorService;
use common\service\ChatService;
use common\service\OptionsService;
use common\service\OrderService;
use common\service\ProjectService;
use common\service\TaskService;
use common\service\TaskUpstreamService;
use common\service\UserService;
use Webman\Stomp\Client;

/**
 * 任务废除行为 消息通知
 */
class TaskStatusChangeBehavior
{
    /**
     * @param $params
     * @return void
     */
    public function run($params)
    {
        /***********  预处理开始  ************/
        $params = BehaviorService::getInstance()->dealParam(
            $params,
            [
                'task_id' => 'intval',
                'task' => '',
                'operate' => 'strval',
                'operate_at' => 'intval',
                'operator' => 'intval',
                'event_type' => 'strval',
            ],
            [
                'task_id' => 0,
                'task' => [],
                'operate' => '',
                'operate_at' => 0,
                'operator' => 0,
                'event_type' => '',
            ],
            'data',
            ['type' => 'task_status_change'],
        );
        /***********  行为判断  ************/
        if ($params === false) {
            return;
        }
        /***********  变量迁移  ************/
        list($taskId, $task, $operate, $operateAt, $operator, $eventType) = $params;
        if (empty($taskId) || empty($task)) {
            return;
        }
        /***********  预处理结束  ************/

        /***********  原逻辑迁移  ************/
        if ($eventType == 'assign_withdraw') {
            return;
        }
        $messageGenerated = [];
        try {
            $enable = $operate === 'enable';
            $queryFields = [
                'task.id',
                'task.name',
                'task.executor',
                'task.tenant_id',
                'task.project_id',
                'task.assignee_producer',
                'task.department_id',
                'task.entity_module_id',
                'task.executor_type',
                'task.step_category_id',

                'entity.id',
                'entity.name',
                'entity.initial_episode_code',
                'entity.showings_number',
                'entity.tenant_id',
                'entity.module_id',
                'entity.project_id',
                'entity.created_by',
                'entity.json',

            ];

            $sameEntityIdList = [];
            $realExecuteTask = model(TaskModel::class)->find($taskId);

            // 记录异常通知
            if (!$enable) {
                $queueData = [
                    'module_code' => 'task',
                    'type' => 'deprecated',
                    'info' => '',
                    'data' => $realExecuteTask,
                ];
                Client::send("abnormal_info_store", build_queue_data_with_xu($queueData));
            }

            $sameEntityIdList[] = $realExecuteTask['entity_id'];
            $project = model(ProjectModel::class)->field('type')->find($realExecuteTask['project_id']);

            $queryDownstreamTaskId = $taskId;
            if ($project['type'] == ProjectModel::TYPE_OUTSOURCE) {
                $sourceTask = OrderService::getInstance()->getSourceTaskByTaskId($realExecuteTask['id']);
                if (!empty($sourceTask)) {
                    $queryDownstreamTaskId = $sourceTask['id'];
                    $sameEntityIdList[] = $sourceTask['entity_id'];
                }
            } else if (in_array($realExecuteTask['executor_type'], TaskModel::OUTSIDE_EXECUTE_TYPE_GROUP)) {
                $realExecuteTask = OrderService::getInstance()->getOutsideTaskByTaskId($realExecuteTask['id']);
                $sameEntityIdList[] = $realExecuteTask['entity_id'];
            }

            $taskIdList = [];
            $downstreamTaskList = TaskUpstreamService::getInstance()->getDownstreamTaskList($queryDownstreamTaskId);
            if (!empty($downstreamTaskList)) {
                $taskIdList = array_column($downstreamTaskList, 'id');
            }
            $taskIdList[] = $realExecuteTask['id'];

            $relatePeopleTasks = model(TaskModel::class)
                ->join('entity on entity.id = task.entity_id')
                ->where(['task.id' => ['IN', implode(',', $taskIdList)]])
                ->field(build_complex_query_fields($queryFields, '__'))
                ->select();
            if (empty($relatePeopleTasks)) {
                return;
            }

            // 抽取数据
            $userIdList = [];
            $projectIdList = [];
            $departmentIdList = [];
            $tenantIdList = [];

            $beOperateTask = null;

            $outsideExecuteTaskList = array_filter($relatePeopleTasks, function ($item) {
                return in_array($item['task__executor_type'], TaskModel::OUTSIDE_EXECUTE_TYPE_GROUP);
            });

            $outsideExecuteTaskTransferToInsideRealTaskList = $this->outsideExecuteTaskTransferToInsideRealTaskList($outsideExecuteTaskList);

            $projectTaskStepCategoryList = [];
            foreach ($relatePeopleTasks as &$relatePeopleTask) {
                $relatePeopleTask = separate_complex_query_data($relatePeopleTask, '__');
                if (in_array($relatePeopleTask['task']['executor_type'], TaskModel::OUTSIDE_EXECUTE_TYPE_GROUP)
                    && array_key_exists($relatePeopleTask['task']['id'], $outsideExecuteTaskTransferToInsideRealTaskList)
                ) {
                    $relatePeopleTask['task'] = $outsideExecuteTaskTransferToInsideRealTaskList[$relatePeopleTask['task']['id']];
                }

                if ($relatePeopleTask['task']['id'] == $realExecuteTask['id']) {
                    $beOperateTask = $relatePeopleTask;
                }

                // 项目环节打组
                if (!in_array($relatePeopleTask['task']['step_category_id'] ?? 0, $projectTaskStepCategoryList[$relatePeopleTask['task']['project_id']] ?? [])) {
                    if (!isset($projectTaskStepCategoryList[$relatePeopleTask['task']['project_id']])) {
                        $projectTaskStepCategoryList[$relatePeopleTask['task']['project_id']] = [];
                    }
                    $projectTaskStepCategoryList[$relatePeopleTask['task']['project_id']][] = $relatePeopleTask['task']['step_category_id'];
                }
                $userIdList[$relatePeopleTask['task']['executor']] = $relatePeopleTask['task']['executor'];
                $userIdList[$relatePeopleTask['task']['assignee_producer']] = $relatePeopleTask['task']['assignee_producer'];
                $projectIdList[$relatePeopleTask['task']['project_id']] = $relatePeopleTask['task']['project_id'];
                $departmentIdList[$relatePeopleTask['task']['department_id']] = $relatePeopleTask['task']['department_id'];
                $tenantIdList[$relatePeopleTask['task']['tenant_id']] = $relatePeopleTask['task']['tenant_id'];
            }

            unset($departmentIdList[0], $tenantIdList[0], $projectIdList[0]);

            // 项目生产制片查询 组装项目生产制片map
//            $projectMemberList = model(ProjectMemberModel::class)
//                ->where([
//                    'project_id' => ['IN', implode(',', $projectIdList)],
//                    'role_code' => TaskService::EXECUTIVE_PRODUCER_CODE,
//                ])
//                ->field('project_id,user_id')
//                ->group('project_id,user_id')
//                ->select();
//            $projectMemberMap = [];
//            foreach ($projectMemberList as $projectMemberItem) {
//                $projectMemberMap[$projectMemberItem['project_id']][] = $projectMemberItem['user_id'];
//                $userIdList[$projectMemberItem['user_id']] = $projectMemberItem['user_id'];
//            }
            unset($userIdList[0]);
            // 根据上面的已有user_id 查询当前系统userMap
            $userList = [];
            if (!empty($userIdList)) {
                $userList = model(UserModel::class)->where(['id' => ['IN', implode(',', $userIdList)]])->field('id,name,union_id')->select();
                $userList = array_column($userList, null, 'id');
            }

            // 根据部门id查询组长 组装部门组长map
//            $userDepartmentMap = [];
//            if (!empty($departmentIdList)) {
//                $filter = [
//                    'tenant_id' => ['-in', implode(',', $tenantIdList)],
//                    'department_id' => ['-in', implode(',', $departmentIdList)],
//                    'role_code' => TaskService::HEADMAN_CODE,
//                ];
//                $userDepartmentMap = UserService::getInstance()->getDepartmentSaasUserMap($filter);
//                foreach ($userDepartmentMap as $departmentUserList) {
//                    foreach ($departmentUserList as $departmentUser) {
//                        $userList[$departmentUser['id']] = $departmentUser;
//                    }
//                }
//            }
            if (empty($userList)) {
                return;
            }
            $templateId = OptionsService::getInstance()->getTaskRemindCommonTemplateId();
            unset($relatePeopleTask);
            $beOperateTaskName = $this->buildTaskName($beOperateTask);
            $chatService = ChatService::getInstance();
            $operator = model(UserModel::class)->find($operator);


            $unionIdListCc = [];
            // 按项目查询配置
//            foreach ($projectTaskStepCategoryList as $projectId => $taskStepCategoryList) {
//                // 抄送给这些环节 配置的【环节制片】
//                $unionIdListCcTmp = ProjectService::getInstance()->projectConfigMessageReceiverUnionIdList([
//                    'project_id' => $projectId,
//                    'step_category_id' => $taskStepCategoryList,
//                    'role_code_list' => ['step_producer'],
//                ], true);
//                $unionIdListCc[$projectId] = $unionIdListCcTmp;
//            }
            // 对每个任务进行单独通知
            foreach ($relatePeopleTasks as $relatePeopleTask) {

                if ($relatePeopleTask['task']['id'] == $realExecuteTask['id']) {

                    if ($enable) {
                        $noteText = '废除的任务' . $beOperateTaskName . '被启用了';
                        $messageActionType = 'entity_step_task_enabled';
                    } else {
                        $noteText = '任务' . $beOperateTaskName . '被废除了';
                        $messageActionType = 'entity_step_task_disabled';
                    }

                    // 会话消息直接发送
                    try {
                        $chat = $chatService->createEntityChat($relatePeopleTask['entity']);
                        $message = [
                            'type' => $messageActionType,
                            'replace' => [
                                'be_operate_task_name' => trim($beOperateTaskName, '】【'),
                                'operator' => ['id' => $operator['union_id'], 'name' => $operator['name']],
                            ],
                        ];
                        $chatService->pushEntityTaskMessage($message, $chat);
                    } catch (\Throwable $e) {
                        trace(format_exception_info($e), 'ERR');
                    }


                } else {

                    $currentTaskName = $this->buildTaskName($relatePeopleTask);

                    if (in_array($relatePeopleTask['entity']['id'], $sameEntityIdList)) {
                        $taskRelation = '上游';
                    } else {
                        $taskRelation = '关联';
                    }

                    if ($enable) {
                        $messageActionType = 'entity_step_task_relate_task_enabled';
                        $noteText = '任务' . $currentTaskName . '的' . $taskRelation . $beOperateTaskName . '被启用了，请注意文件替换';
                    } else {
                        $messageActionType = 'entity_step_task_relate_task_disabled';
                        $noteText = '任务' . $currentTaskName . '的' . $taskRelation . $beOperateTaskName . '被废除了，请注意文件替换';
                    }

                    // 会话消息直接发送
                    try {
                        $chat = $chatService->createEntityChat($relatePeopleTask['entity']);
                        $message = [
                            'type' => $messageActionType,
                            'replace' => [
                                'be_operate_task_name' => trim($beOperateTaskName, '】【'),
                                'relation_text' => $taskRelation,
                                'current_task_name' => trim($currentTaskName, '】【'),
                                'operator' => ['id' => $operator['union_id'], 'name' => $operator['name']],
                            ],
                        ];
                        $chatService->pushEntityTaskMessage($message, $chat);
                    } catch (\Throwable $e) {
                        trace(format_exception_info($e), 'ERR');
                    }

                }

                $currentUserIdList = [];

                if ($relatePeopleTask['task']['executor'] > 0) {
                    $currentUserIdList[] = $relatePeopleTask['task']['executor'];
                }
                if ($relatePeopleTask['task']['assignee_producer'] > 0) {
                    $currentUserIdList[] = $relatePeopleTask['task']['assignee_producer'];
                }
                if ($relatePeopleTask['task']['project_id'] > 0 && isset($projectMemberMap[$relatePeopleTask['task']['project_id']])) {
                    foreach ($projectMemberMap[$relatePeopleTask['task']['project_id']] as $userId) {
                        $currentUserIdList[] = $userId;
                    }
                }

                $currentUserIdList = array_unique($currentUserIdList);
                $currentUserList = [];
                foreach ($currentUserIdList as $userId) {
                    if (isset($userList[$userId])) {
                        $currentUserList[$userId] = $userList[$userId];
                    }
                }

                if ($relatePeopleTask['task']['department_id'] > 0 && isset($userDepartmentMap[$relatePeopleTask['task']['department_id']])) {
                    foreach ($userDepartmentMap[$relatePeopleTask['task']['department_id']] as $user) {
                        $currentUserList[$user['id']] = $user;
                    }
                }

                if (!empty($relatePeopleTask['task']['project_id'] ?? 0) && !empty($relatePeopleTask['task']['step_category_id'] ?? 0)) {
                    foreach ($unionIdListCc[$relatePeopleTask['task']['project_id']][$relatePeopleTask['task']['step_category_id']] ?? [] as $userUnionId) {
                        $currentUserList[$userUnionId] = ['union_id' => $userUnionId];
                    }
                }

                if (empty($currentUserList)) {
                    continue;
                }
                /**
                 * 发送小助手消息
                 */
                $notifyParam = [
                    'first' => '任务状态变更通知',
                    'note_text' => $noteText,
                    'remark' => "请及时查看",
                    'tenant_id' => $relatePeopleTask['task']['tenant_id'],
                    'project_id' => $relatePeopleTask['task']['project_id'],
                    'entity_id' => $relatePeopleTask['entity']['id'],
                    'task_id' => $relatePeopleTask['task']['id'],
                    'module_code' => in_array(module_by_id($relatePeopleTask['entity']['module_id'])['code'], ['design', 'level', 'asset']) ? 'asset' : 'shot',
                    'message_key' => 'task_close_operation',
                ];
                foreach ($currentUserList as $user) {
                    $unionId = $user['union_id'];
                    // 异步发送通知
                    $messageGenerated[] = [
                        "param" => $notifyParam,
                        'receiver' => $unionId,
                        'template_id' => $templateId,
                        'content_type' => 'card_message',
                        'notice_type' => 'message_demand',
                        'is_popup' => 1,
                        'message_key' => $notifyParam['message_key'],
                    ];
                }
            }

        } catch (\Throwable $e) {
            trace(format_exception_info($e), 'ERR');
        }

        /***********  发送新的队列  ************/
        foreach ($messageGenerated as $message) {
            Client::send('common_message_pushing', build_queue_data_with_xu([
                'message_generated' => [$message],
            ]));
        }
        /***********  结束  ************/
    }


    /**
     * 生成任务名称
     * @param mixed $relatePeopleTask
     * @return string
     */
    private function buildTaskName($relatePeopleTask)
    {
        return '【' . $relatePeopleTask['entity']['initial_episode_code'] . '/'
            . $relatePeopleTask['entity']['showings_number'] . '/' . $relatePeopleTask['entity']['name']
            . '/' . $relatePeopleTask['task']['name'] . '】';
    }

    /**
     * 查询把外包的任务对应的乙方任务
     * @param $outsideExecuteTaskList
     * @return array
     */
    private function outsideExecuteTaskTransferToInsideRealTaskList($outsideExecuteTaskList)
    {
        if (empty($outsideExecuteTaskList)) {
            return [];
        }
        $taskIdList = [];
        foreach ($outsideExecuteTaskList as $outsideExecuteTask) {
            $taskIdList[] = $outsideExecuteTask['task__id'];
        }
        return OrderService::getInstance()->getOutsideTaskListByTaskIdList($taskIdList);
    }
}
